package com.pro01.apirednote.service.serviceImpl;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.pro01.apirednote.pojo.Content;
import com.pro01.apirednote.pojo.PageResult;
import com.pro01.apirednote.service.CacheService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
@RequiredArgsConstructor
public class CacheServiceImpl implements CacheService {

    private final RedisTemplate<String, Object> redisTemplate;
    private final ObjectMapper objectMapper;
    private static final String SEARCH_CACHE_PREFIX = "search:";

    @Override
    public void cacheSearchResult(String key, PageResult<Content> pageResult, long expireSeconds) {
        try {
            String cacheKey = SEARCH_CACHE_PREFIX + key;
            redisTemplate.opsForValue().set(cacheKey, pageResult, expireSeconds, TimeUnit.SECONDS);
            log.info("搜索结果已缓存，key: {}, 过期时间: {}秒", cacheKey, expireSeconds);
        } catch (Exception e) {
            log.error("缓存搜索结果失败：{}", e.getMessage(), e);
            // 缓存失败不影响主流程，只记录日志
        }
    }

    @Override
    public PageResult<Content> getCachedSearchResult(String key) {
        try {
            String cacheKey = SEARCH_CACHE_PREFIX + key;
            Object cachedResult = redisTemplate.opsForValue().get(cacheKey);
            if (cachedResult != null) {
                log.info("命中缓存：{}", cacheKey);
                
                // 处理不同类型的缓存结果
                if (cachedResult instanceof PageResult) {
                    return (PageResult<Content>) cachedResult;
                } else if (cachedResult instanceof Map) {
                    // 处理被反序列化为Map的情况
                    Map<String, Object> resultMap = (Map<String, Object>) cachedResult;
                    
                    // 获取total字段
                    long total = 0;
                    if (resultMap.containsKey("total")) {
                        if (resultMap.get("total") instanceof Number) {
                            total = ((Number) resultMap.get("total")).longValue();
                        }
                    }
                    
                    // 获取并转换records字段
                    List<Content> records = null;
                    if (resultMap.containsKey("records")) {
                        Object recordsObj = resultMap.get("records");
                        if (recordsObj instanceof List) {
                            // 将records列表中的每个元素转换为Content对象
                            records = objectMapper.convertValue(recordsObj, 
                                    new TypeReference<List<Content>>() {});
                        }
                    }
                    
                    // 创建新的PageResult对象
                    return new PageResult<>(total, records);
                }
            }
        } catch (Exception e) {
            log.error("获取缓存搜索结果失败：{}", e.getMessage(), e);
            // 获取缓存失败不影响主流程，只记录日志
        }
        return null;
    }

    @Override
    public void deleteCache(String key) {
        try {
            String cacheKey = SEARCH_CACHE_PREFIX + key;
            redisTemplate.delete(cacheKey);
            log.info("缓存已删除：{}", cacheKey);
        } catch (Exception e) {
            log.error("删除缓存失败：{}", e.getMessage(), e);
        }
    }

    @Override
    public String generateSearchKey(String searchType, String keyword, int pageNum, int pageSize) {
        // 生成唯一的缓存键
        return searchType + ":" + keyword + ":" + pageNum + ":" + pageSize;
    }
    
    @Override
    public long clearAllSearchCache() {
        try {
            Set<String> keys = redisTemplate.keys(SEARCH_CACHE_PREFIX + "*");
            if (keys != null && !keys.isEmpty()) {
                long count = redisTemplate.delete(keys);
                log.info("已清除所有搜索缓存，共{}条", count);
                return count;
            }
        } catch (Exception e) {
            log.error("清除所有搜索缓存失败：{}", e.getMessage(), e);
        }
        return 0;
    }
    
    @Override
    public long clearSearchCacheContainingContent(Long contentId) {
        if (contentId == null) {
            return 0;
        }
        
        long clearedCount = 0;
        try {
            // 获取所有搜索缓存键
            Set<String> cacheKeys = redisTemplate.keys(SEARCH_CACHE_PREFIX + "*");
            if (cacheKeys == null || cacheKeys.isEmpty()) {
                return 0;
            }
            
            // 遍历所有缓存键
            for (String cacheKey : cacheKeys) {
                try {
                    Object cachedObj = redisTemplate.opsForValue().get(cacheKey);
                    if (cachedObj == null) {
                        continue;
                    }
                    
                    List<Content> contents = null;
                    
                    // 处理不同类型的缓存结果
                    if (cachedObj instanceof PageResult) {
                        PageResult<Content> pageResult = (PageResult<Content>) cachedObj;
                        contents = pageResult.getRecords();
                    } else if (cachedObj instanceof Map) {
                        Map<String, Object> resultMap = (Map<String, Object>) cachedObj;
                        if (resultMap.containsKey("records")) {
                            Object recordsObj = resultMap.get("records");
                            if (recordsObj instanceof List) {
                                contents = objectMapper.convertValue(recordsObj, 
                                        new TypeReference<List<Content>>() {});
                            }
                        }
                    }
                    
                    // 检查内容列表中是否包含指定的contentId
                    if (contents != null) {
                        boolean containsContent = contents.stream()
                                .anyMatch(content -> contentId.equals(content.getId()));
                        
                        if (containsContent) {
                            // 如果包含指定内容，删除该缓存
                            redisTemplate.delete(cacheKey);
                            clearedCount++;
                            log.info("清除包含内容ID {} 的搜索缓存：{}", contentId, cacheKey);
                        }
                    }
                } catch (Exception e) {
                    log.error("检查缓存 {} 是否包含内容ID {} 时出错：{}", cacheKey, contentId, e.getMessage());
                    // 继续处理下一个缓存
                }
            }
            
            log.info("已清除包含内容ID {} 的搜索缓存，共{}条", contentId, clearedCount);
        } catch (Exception e) {
            log.error("清除包含内容ID {} 的搜索缓存失败：{}", contentId, e.getMessage(), e);
        }
        
        return clearedCount;
    }
} 